昨天我們實作了很簡陋的api,今天我們要將它重構成好一點點,至少加入一些錯誤處理。
400、500這些status code,讓我們再發生錯誤的時候,可以得到多一點訊息,而不用面對預設的漏漏長的訊息~ 透過好的錯誤訊息,可以讓我們知道到底發生了甚麼事情,讓維運的夥伴看到後,可以快速的解決難題。
package controller
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import model.*
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
fun customerVOToCustomer(customerVO: CustomerVO) =
when {
customerVO.contactInfo.contains("@") -> Customer(
Name(customerVO.name),
Email(customerVO.contactInfo),
Age(customerVO.age)
)
customerVO.contactInfo.length > 8 -> throw Error("contactInfo Too Long")
else -> Customer(Name(customerVO.name), Phone(customerVO.contactInfo), Age(customerVO.age))
}
@RestController
@SpringBootApplication
open class MyApplication {
private val customerList = mutableListOf<Customer>()
@GetMapping("/api/v1/customers")
fun getAllCustomers(): ResponseEntity<String> {
if (customerList.isEmpty())
return ResponseEntity.status(404).body("Not Found any customers!")
try {
Json.encodeToString(customerList)
} catch (e: Exception) {
return ResponseEntity.status(500).body(e.toString())
}.let {
return ResponseEntity.ok(it)
}
}
@PostMapping("/api/v1/customers")
fun createCustomer(@RequestBody newCustomer: String): ResponseEntity<String> {
Json.decodeFromString<CustomerVO>(newCustomer).let {
try {
customerVOToCustomer(it)
} catch (e: Error) {
return ResponseEntity.status(400).body(e.toString())
}
}.let {
customerList.add(it)
it
}.let {
try {
Json.encodeToString(it)
} catch (e: Exception) {
return ResponseEntity.status(500).body(e.toString())
}
}.let {
return ResponseEntity.ok(it)
}
}
@PutMapping("/api/v1/customers")
fun updateCustomer(@RequestBody newCustomer: String): ResponseEntity<String> {
Json.decodeFromString<CustomerVO>(newCustomer).let {
customerVOToCustomer(it)
}.let { validatedCustomer ->
return when (val index = customerList.indexOfFirst { it.name == validatedCustomer.name }) {
-1 -> ResponseEntity.status(404).body("Not Found")
else -> {
customerList.set(index, validatedCustomer)
ResponseEntity.ok("Modify success")
}
}
}
}
@DeleteMapping("/api/v1/customers")
fun DeleteCustomer(@RequestBody newCustomer: String): ResponseEntity<String> {
Json.decodeFromString<CustomerVO>(newCustomer).let {
customerVOToCustomer(it)
}.let { validatedCustomer ->
return when (val index = customerList.indexOfFirst { it.name == validatedCustomer.name }) {
-1 -> ResponseEntity.status(404).body("Not Found")
else -> {
customerList.removeAt(index)
ResponseEntity.ok("Delete success")
}
}
}
}
}
fun main(args: Array<String>) {
runApplication<MyApplication>(*args)
}
我們今天將一些常見的錯誤做了處理,至少回傳一些大家看得懂的status,並且透過一些訊息,我們可以知道大概發生了什麼樣的錯誤,比如說找不到顧客呀,成功修改顧客資訊等,當我們寫得越清楚,當真正錯誤發生時,我們可以一目了然的知道要怎麼處理,接下來,明天要再對錯誤更進一步的進行處理,加上domain type的概念。
這邊附上GPT夥伴幫我們製作常見的status code介紹。
狀態碼 | 說明 | 用途範例 |
---|---|---|
200 | OK | 請求成功完成。 |
201 | Created | 請求成功,並且新資源已經被創建。 |
204 | No Content | 請求成功,但沒有返回主體內容。 |
400 | Bad Request | 請求無效或格式錯誤。 |
401 | Unauthorized | 未經授權,需要驗證。 |
403 | Forbidden | 請求被拒絕,沒有訪問權限。 |
404 | Not Found | 請求的資源不存在。 |
405 | Method Not Allowed | 不允許使用該HTTP方法。 |
500 | Internal Server Error | 伺服器內部錯誤,請求未完成。 |
502 | Bad Gateway | 伺服器作為網關或代理,從上游伺服器收到無效回應。 |
503 | Service Unavailable | 伺服器暫時無法處理請求(通常用於維護模式)。 |
504 | Gateway Timeout | 伺服器作為網關或代理,未及時收到上游伺服器的回應。 |